/*********************************************************************************
 *      Copyright:  (C) 2024 LingYun<iot25@lingyun>
 *                  All rights reserved.
 *
 *       Filename:  log_system.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(09/12/24)
 *         Author:  LingYun <iot25@lingyun>
 *      ChangeLog:  1, Release initial version on "09/12/24 16:22:07"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>

#include "log_system.h"
#include "get_time.h"

#define LOG_FILE_MAX_SIZE (10 * 1024 * 1024)  // 日志文件最大大小：10MB

//全局日志配置
static LogConfig log_config = {0};

//初始化日志系统
int log_init(const char *log_file_name,LogLevel log_level, int console_output)
{
	if(log_config.log_file != NULL)
	{
		return -1;  //日志系统已经被初始化
	}

	//打开日志文件
	strncpy(log_config.log_file_name, log_file_name, sizeof(log_config.log_file_name) - 1);
	log_config.log_file = fopen(log_file_name,"a");
	if( log_config.log_file == NULL )
	{
		printf("Open log system failure:%s.\n",strerror(errno));
		return -1;
	}

	log_config.log_level = log_level;
	log_config.console_output = console_output;

	return 0;
}

//日志文件回滚，如果文件超过最大的容量，重命名当前文件并创建新文件
void log_rollover()
{
	if( log_config.log_file == NULL )
		return ;

	//获取当前日志文件的大小
	fseek(log_config.log_file, 0,SEEK_END);
	long file_size = ftell(log_config.log_file);
	if( file_size >= LOG_FILE_MAX_SIZE )
	{
		fclose(log_config.log_file);  //关闭当前日志文件

		//重命名当前日志文件
		char	new_file_name[300];
		snprintf(new_file_name,sizeof(new_file_name), "%s.old", log_config.log_file_name);
		rename(log_config.log_file_name, new_file_name);

		//创建一个新的日志文件
		log_config.log_file = fopen(log_config.log_file_name, "a");
		if(log_config.log_file == NULL)
		{
			printf("Create new log system failure:%s.\n",strerror(errno));
		}
	}
}

//写日志
void log_write(LogLevel level, const char *file, const char *func, int line, const char *fmt,...)
{
	//检查日志级别是否满足条件
	if( level < log_config.log_level )
	{
		return ;
	}

	const char *level_str = NULL;
	switch( level )
	{
		case LOG_DEBUG: level_str = "DEBUG" ; break;
		case LOG_INFO: level_str = "INFO" ; break;
		case LOG_WARN: level_str = "WARN" ; break;
		case LOG_ERROR: level_str = "error" ; break;
	}

	//获取当前时间
	char time_buf[80];
	get_time(time_buf,sizeof(time_buf));

	//准备日志格式
	char		log_msg[1024];
	va_list		args;
	va_start(args,fmt);
	vsnprintf(log_msg,sizeof(log_msg),fmt,args);
	va_end(args);

	//输出到标准输出
	if(log_config.console_output)
	{
		printf("[%s] [%s] [%s:%d] [%s] %s.\n",time_buf,level_str,file,line,func,log_msg);
	}

	//输出到文件
	if(log_config.log_file != NULL)
	{
		log_rollover();  //检查是否是需要回滚日志文件

		fprintf(log_config.log_file, "[%s] [%s] [%s:%d] [%s] %s.\n",time_buf,level_str,file,line,func,log_msg);

		fflush(log_config.log_file);
	}
} 

//关闭日志系统
void log_close()
{
	if(log_config.log_file != NULL)
	{
		fclose(log_config.log_file);
		log_config.log_file = NULL;
	}
}
